import { ILyric, parseLyric } from '@/utils/parse-lyric'
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import { getSongDetail, getSongLyric } from '@/apis/player'
import { IRootState } from '@/Hooks/hook'

interface IThunkState {
  state: IRootState
}
export const fetchCurrentSongAction = createAsyncThunk<
  void,
  number,
  IThunkState
>('currentSong', (id: number, { dispatch, getState }) => {
  // 准备播放某一首歌曲时, 分成两种情况
  // 1.从列表尝试是否可以获取到这首歌
  const playSongList = getState().player.playSongList
  const findIndex = playSongList.findIndex((item: any) => item.id === id)
  if (findIndex === -1) {
    // 没有找到相同的
    // 1.获取歌曲信息
    getSongDetail(id).then((res) => {
      // 1.获取song
      if (!res.songs.length) return
      const song = res.songs[0]

      // 2.将song放到currentSong中
      const newPlaySongList = [...playSongList]
      newPlaySongList.push(song)
      dispatch(changeCurrentSongAction(song))
      dispatch(changePlaySongListAction(newPlaySongList))
      dispatch(changePlaySongIndexAction(newPlaySongList.length - 1))
    })
  } else {
    // 找到了相同的item
    const song = playSongList[findIndex]
    dispatch(changeCurrentSongAction(song))
    dispatch(changePlaySongIndexAction(findIndex))
  }

  // 2.获取歌词数据
  getSongLyric(id).then((res) => {
    // 1.获取歌词的字符串
    const lyricString = res.lrc.lyric
    // 2.对歌词进行解析(一个个对象)
    const lyrics = parseLyric(lyricString)
    // 3.将歌词放到state中
    dispatch(changeLyricsAction(lyrics))
  })
})

export const changeMusicAction = createAsyncThunk<void, boolean, IThunkState>(
  'changemuisc',
  (isNext, { dispatch, getState }) => {
    // 1.获取state中的数据
    const player = getState().player
    const playMode = player.playMode
    const songIndex = player.playSongIndex
    const songList = player.playSongList

    // 2.根据不同的模式计算不同的下一首歌曲的索引
    let newIndex = songIndex
    if (playMode === 1) {
      // 随机播放
      newIndex = Math.floor(Math.random() * songList.length)
    } else {
      // 单曲顺序和顺序播放
      newIndex = isNext ? songIndex + 1 : songIndex - 1
      if (newIndex > songList.length - 1) newIndex = 0
      if (newIndex < 0) newIndex = songList.length - 1
    }

    // 3.获取当前的歌曲
    const song = songList[newIndex]
    dispatch(changeCurrentSongAction(song))
    dispatch(changePlaySongIndexAction(newIndex))

    // 4.请求新的歌词
    getSongLyric(song.id).then((res: any) => {
      // 1.获取歌词的字符串
      const lyricString = res.lrc.lyric
      // 2.对歌词进行解析(一个个对象)
      const lyrics = parseLyric(lyricString)
      // 3.将歌词放到state中
      dispatch(changeLyricsAction(lyrics))
    })
  }
)

interface IPlayerState {
  currentSong: any
  lyrics: ILyric[]
  lyricIndex: number
  playSongList: any[]
  playSongIndex: number
  playMode: number
}
const initialState: IPlayerState = {
  currentSong: {},
  lyrics: [],
  lyricIndex: -1,
  playSongList: [
    {
      name: '看不见的风景',
      mainTitle: null,
      additionalTitle: null,
      id: 167771,
      pst: 0,
      t: 0,
      ar: [
        {
          id: 5771,
          name: '许嵩',
          tns: [],
          alias: []
        }
      ],
      alia: [],
      pop: 95,
      st: 0,
      rt: '600902000009525568',
      fee: 8,
      v: 49,
      crbt: null,
      cf: '',
      al: {
        id: 16942,
        name: '半城烟沙',
        picUrl:
          'https://p1.music.126.net/VUtLfAqLDYMn2dfy0qlRkw==/109951166118678136.jpg',
        tns: [],
        pic_str: '109951166118678136',
        pic: 109951166118678140
      },
      dt: 277826,
      h: {
        br: 320000,
        fid: 0,
        size: 11115668,
        vd: -32903,
        sr: 44100
      },
      m: {
        br: 192000,
        fid: 0,
        size: 6669418,
        vd: -30297,
        sr: 44100
      },
      l: {
        br: 128000,
        fid: 0,
        size: 4446293,
        vd: -28644,
        sr: 44100
      },
      sq: {
        br: 1527337,
        fid: 0,
        size: 53046996,
        vd: -32908,
        sr: 44100
      },
      hr: null,
      a: null,
      cd: '1',
      no: 9,
      rtUrl: null,
      ftype: 0,
      rtUrls: [],
      djId: 0,
      copyright: 2,
      s_id: 0,
      mark: 17179877376,
      originCoverType: 1,
      originSongSimpleData: null,
      tagPicList: null,
      resourceState: true,
      version: 30,
      songJumpInfo: null,
      entertainmentTags: null,
      awardTags: null,
      displayTags: null,
      single: 0,
      noCopyrightRcmd: null,
      mv: 0,
      rtype: 0,
      rurl: null,
      mst: 9,
      cp: 14026,
      publishTime: 1270915200000
    },
    {
      name: 'Prelude, Op. 37/1 In Bb',
      mainTitle: null,
      additionalTitle: null,
      id: 2078378,
      pst: 0,
      t: 0,
      ar: [
        {
          id: 45773,
          name: 'Vladimir Sofronitsky',
          tns: [],
          alias: []
        }
      ],
      alia: [],
      pop: 10,
      st: 0,
      rt: '',
      fee: 0,
      v: 26,
      crbt: null,
      cf: '',
      al: {
        id: 209361,
        name: 'Sofronitsky At The Scriabin Museum, 1960',
        picUrl:
          'https://p2.music.126.net/sYuroC0RKgkPUye7EQBlrQ==/1651466464921153.jpg',
        tns: [],
        pic: 1651466464921153
      },
      dt: 109000,
      h: {
        br: 320000,
        fid: 0,
        size: 4396107,
        vd: 21585,
        sr: 44100
      },
      m: {
        br: 192000,
        fid: 0,
        size: 2637753,
        vd: 24064,
        sr: 44100
      },
      l: {
        br: 128000,
        fid: 0,
        size: 1758576,
        vd: 28453,
        sr: 44100
      },
      sq: null,
      hr: null,
      a: null,
      cd: '1',
      no: 5,
      rtUrl: null,
      ftype: 0,
      rtUrls: [],
      djId: 0,
      copyright: 2,
      s_id: 0,
      mark: 131072,
      originCoverType: 0,
      originSongSimpleData: null,
      tagPicList: null,
      resourceState: true,
      version: 7,
      songJumpInfo: null,
      entertainmentTags: null,
      awardTags: null,
      displayTags: null,
      single: 0,
      noCopyrightRcmd: null,
      mv: 0,
      rtype: 0,
      rurl: null,
      mst: 9,
      cp: 0,
      publishTime: 1228060800007
    }
  ],
  playSongIndex: -1,

  playMode: 0 // 0:顺序播放 1:随机播放 2:单曲循环
}

const playerSlice = createSlice({
  name: 'player',
  initialState,
  reducers: {
    changeCurrentSongAction(state, { payload }) {
      state.currentSong = payload
    },
    changeLyricsAction(state, { payload }) {
      state.lyrics = payload
    },
    changeLyricIndexAction(state, { payload }) {
      state.lyricIndex = payload
    },
    changePlaySongIndexAction(state, { payload }) {
      state.playSongIndex = payload
    },
    changePlaySongListAction(state, { payload }) {
      state.playSongList = payload
    },
    changePlayModeAction(state, { payload }) {
      state.playMode = payload
    }
  }
})

export const {
  changeCurrentSongAction,
  changeLyricsAction,
  changeLyricIndexAction,
  changePlaySongIndexAction,
  changePlaySongListAction,
  changePlayModeAction
} = playerSlice.actions
export default playerSlice.reducer
